package com.ttg.web.service.job.model.impl;

import com.google.common.util.concurrent.ListenableFuture;
import com.ttg.common.annotation.TaskRunMethod;
import com.ttg.common.dto.TaskBaseDTO;
import com.ttg.common.entities.BasePage;
import com.ttg.common.utils.BigDecimalUtils;
import com.ttg.common.utils.DateTimeUtil;
import com.ttg.common.vo.TaskResultVO;
import com.ttg.model.dto.job.ModelAcctPageDTO;
import com.ttg.model.pojo.ModelAccountMonth;
import com.ttg.model.vo.ModelAcctVO;
import com.ttg.web.dao.BankAccountPrimitiveDao;
import com.ttg.web.dao.ModelAccountMonthDao;
import com.ttg.web.juc.TasktemplateHelper;
import com.ttg.web.service.job.JobCommon;
import com.ttg.web.service.job.model.ModelAcctJobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Description：
 * Author: chenyou
 * Date: 2025/11/14 11:03
 * Company: ttg
 * Copyright: Copyright (c) 2025
 */
@Service
@TaskRunMethod(value = "saveModelAcctDataByMonthTask")
public class ModelAcctJobServiceImpl extends JobCommon implements ModelAcctJobService {
    @Value("${tlinx.isJuc:false}")
    private volatile Boolean isJuc;//是否启用异步回调
    @Autowired
    private TasktemplateHelper tasktemplateHelper;
    @Autowired
    private BankAccountPrimitiveDao accountPrimitiveDao;
    @Autowired
    private ModelAccountMonthDao modelAccountMonthDao;

    private static final int BATCH_SIZE = 499;

    @Override
    public TaskResultVO saveModelAcctDataByMonth(TaskBaseDTO dto) {
        dto = getCheckYearAndMonth(dto);
        Integer firstDay = DateTimeUtil.getFirstDayOnMonth(dto.getYear(),dto.getMonth());
        Integer lastDay = DateTimeUtil.getLastDayOnMonth(dto.getYear(),dto.getMonth());
        //基于原始数据->按月归集商户模型数据

        //分页查询账户编号list,执行跑批任务
        ModelAcctPageDTO countDTO = new ModelAcctPageDTO();
        countDTO.setFirstDay(firstDay);
        countDTO.setLastDay(lastDay);
        countDTO.setPageSize(BATCH_SIZE);
        BasePage<Long> acctNoCount = accountPrimitiveDao.getAcctNosByPage(countDTO);
        Long pages = acctNoCount.getPages();
        List<ModelAcctPageDTO> pageDTOS = new ArrayList<>();
        for(int i=1;i<=pages;i++){
            ModelAcctPageDTO pageDTO = new ModelAcctPageDTO();
            pageDTO.setFirstDay(firstDay);
            pageDTO.setLastDay(lastDay);
            pageDTO.setPageSize(BATCH_SIZE);
            pageDTO.setPage(i);
            pageDTOS.add(pageDTO);
        }
        //删除原记录
        modelAccountMonthDao.deleteByYearAndMonth(dto.getYear(),dto.getMonth());
        List<ListenableFuture<TaskResultVO>> futures = new ArrayList<>();
        List<TaskResultVO> results = new ArrayList<>();
        for(ModelAcctPageDTO pageDTO:pageDTOS){
            if(isJuc){
                futures.add(tasktemplateHelper.submit(this,dto,pageDTO));
            }else {
                TaskResultVO result = saveModelAcctDataByMonthTask(dto,pageDTO);
                results.add(result);
            }
        }
        return taskResult(results,futures,isJuc);
    }

    public TaskResultVO saveModelAcctDataByMonthTask(TaskBaseDTO reqDTO,ModelAcctPageDTO pageDTO){
        Integer firstDay = DateTimeUtil.getFirstDayOnMonth(reqDTO.getYear(),reqDTO.getMonth());
        Integer lastDay = DateTimeUtil.getLastDayOnMonth(reqDTO.getYear(),reqDTO.getMonth());
        Integer days = DateTimeUtil.daysBetween(String.valueOf(firstDay),String.valueOf(lastDay)) + 1;
        BasePage<Long> acctNos = accountPrimitiveDao.getAcctNosByPage(pageDTO);
        List<ModelAcctVO> acctSumVO = accountPrimitiveDao.getAllAcctModel(firstDay,lastDay,acctNos.getList());
        List<ModelAccountMonth> monthList =
                acctSumVO.stream().map(o -> {
                    ModelAccountMonth accountMonth = new ModelAccountMonth();
                    accountMonth.setYear(reqDTO.getYear());
                    accountMonth.setMonth(reqDTO.getMonth());
                    accountMonth.setActNo(o.getActNo());
                    accountMonth.setMctNo(o.getMctNo());
                    accountMonth.setVipId(o.getVipId());
                    accountMonth.setActType(o.getActType());
                    accountMonth.setAvgAmt(BigDecimalUtils.div(o.getTimeAmtAum(),days,0));
                    accountMonth.setLastdayAmt(o.getLastdayAmt());
                    accountMonth.setMaxCreditAmt(o.getMaxCreditAmt());
                    accountMonth.setMaxUseCreditAmt(o.getMaxUseCreditAmt());
                    accountMonth.setAvgDepositRate(o.getAvgDepositRate());
                    accountMonth.setAvgCreditRate(o.getAvgCreditRate());
                    accountMonth.setUpdateTime(LocalDateTime.now());
            return accountMonth;
        }).collect(Collectors.toList());

        //保存
        modelAccountMonthDao.saveBatch(monthList);
        return taskReuslt(Status.SUCCESS.getValue(),false,"ok");
    }


}
